(display "Simple factorial test: answers 120  and 2432902008176640000\n")
(define fact (lambda (n) (if (= n 0) 1 (* n (fact (- n 1))))))
(write (fact 5))
(newline)
(write (fact 20))
(newline)

(display "Quote tests\n")
(display "ans: a   ")
(write (quote a))
(newline)
(display "ans: #(a b c)   ")
(write (quote #(a b c)))
(newline)
(display "ans: (+ 1 2)   ")
(write (quote (+ 1 2))) (newline)
(display "ans: a   ") (write 'a) (newline)
(display "ans: #(a b c))   ") (write '#(a b c)) (newline)
(display "ans: ()   ") (write '()) (newline)
(display "ans: (+ 1 2)   ") (write '(+ 1 2)) (newline)
(display "ans: (quote a)   ") (write '(quote a)) (newline)
(display "ans: (quote a)   ") (write ''a) (newline)
(display "ans: \"abc\"   ") (write '"abc") (newline)
(display "ans: \"abc\"   ") (write "abc") (newline)
(display "ans: 145932   ") (write '145932) (newline)
(display "ans: 145932   ") (write 145932) (newline)
(display "ans: #t   ") (write '#t) (newline)
(display "ans: #t   ") (write #t) (newline)

(display "\n\nSimple procedure call\n")
(display "ans: 7   ") (write (+ 3 4)) (newline)
(display "Operator expression: ((if #f + *) 3 4)\n")
(display "ans: 12   ") (write ((if #f + *) 3 4)) (newline)

(display "\n\nLambda expressions:\n")
(display "ans: 8   ") (write ((lambda (x) (+ x x)) 4)) (newline)
(display "ans: 3   ")
(define reverse-subtract (lambda (x y) (- y x)))
(write (reverse-subtract 7 10)) (newline)
(display "ans: 10   ")
(define add4 (let ((x 4)) (lambda (y) (+ x y))))
(write (add4 6)) (newline)
(display "ans: (3 4 5 6)   ")
(write ((lambda x x) 3 4 5 6)) (newline)
(display "ans: (5 6)   ")
(write ((lambda (x y . z) z) 3 4 5 6)) (newline)

(display "\n\nif tests:\n")
(display "ans: yes   ") (write (if (> 3 2) 'yes 'no)) (newline)
(display "ans: no   ") (write (if (> 2 3) 'yes 'no)) (newline)
(display "ans: 1   ") (write (if (> 3 2) (- 3 2) (+ 3 2))) (newline)

(display "\n\nset!:\n")
(display "ans: 3   ")
(define x 2) (write (+ x 1)) (newline)
(display "ans: 5   ")
(set! x 4) (write (+ x 1)) (newline)

(display "\n\ncond:\n")
(display "ans: greater   ")
(write (cond ((> 3 2) ' greater) ((< 3 2) 'less))) (newline)
(display "ans: equal   ")
(write (cond ((> 3 3) 'greater) ((< 3 3) 'less) (else 'equal))) (newline)
(display "ans: 2   ")
(write (cond ((assv 'b '((a 2) (b 2))) => cadr) (else #f))) (newline)

(display "\n\ncase:\n")
(display "ans: composite   ")
(write (case (* 2 3) ((2 3 5 7) 'prime) ((1 4 6 8 9) 'composite))) (newline)
(display "ans: uspecifiecified   ")
(write (case (car '(c d)) ((a) 'a) ((b) 'b))) (newline)
(display "ans: consonant   ")
(write (case (car '(c d)) ((a e i o u) 'vowel) ((w y) 'semivowel) (else 'consonant)))
(newline)

(display "\n\nand:\n")
(display "ans: #t   ") (write (and (= 2 2) (> 2 1))) (newline)
(display "ans: #f   ") (write (and (= 2 2) (< 2 1))) (newline)
(display "ans: (f g)   ") (write (and 1 2 'c '(f g))) (newline)
(display "ans: #t   ") (write (and)) (newline)

(display "\n\nor:\n")
(display "ans: #t   ") (write (or (= 2 2) (> 2 1))) (newline)
(display "ans: #t   ") (write (or (= 2 2) (< 2 1))) (newline)
(display "ans: #f   ") (write (or #f #f #f)) (newline)
(display "ans: (b c)   ") (write (or (memq 'b '(a b c)) (/ 3 0))) (newline)

(display "\n\nlet, let*, letrec:\n")
(display "ans: 6   ") (write (let ((x 2) (y 3)) (* x y))) (newline)
(display "ans: 35   ")
(write (let ((x 2) (y 3)) (let ((x 7) (z (+ x y))) (* z x))))
(newline)
(display "ans: 70   ")
(write (let ((x 2) (y 3)) (let* ((x 7) (z (+ x y))) (* z x))))
(newline)
(display "ans: #t   ")
(write
(letrec ((even?
              (lambda (n)
                (if (zero? n) #t (odd? (- n 1)))))
            (odd?
              (lambda (n)
                (if (zero? n) #f (even? (- n 1))))))
  (even? 88))) (newline)

(display "\n\nbegin:\n")
(display "ans: 6   ")
(define x 0)
(write (begin (set! x 5) (+ x 1))) (newline)
(display "ans: unspecified and outputs \"4 plus 1 equals 5\"\n")
(write (begin (display "4 plus one equal ") (display (+ 4 1)))) (newline)

(display "\n\ndo:\n")
(display "ans: #(0 1 2 3 4)   ")
(write
  (do ((vec (make-vector 5))
      (i 0 (+ i 1)))
    ((= i 5) vec)
  (vector-set! vec i i))
) (newline)
(display "ans: 25   ")
(write
  (let ((x '(1 3 5 7 9)))
    (do ((x x (cdr x))
      (sum 0 (+ sum (car x))))
      ((null? x) sum)))
) (newline)

(display "\n\nnamed let:\n")
(display "ans: ((6 1 3) (-5 -2))   ")
(write
  (let loop ((numbers '(3 -2 1 6 -5)) (nonneg '()) (neg '()))
    (cond ((null? numbers) (list nonneg neg))
             ((>= (car numbers) 0)
              (loop (cdr numbers) (cons (car numbers) nonneg) neg))
             ((< (car numbers) 0)
              (loop (cdr numbers) nonneg (cons (car numbers) neg)))))
) (newline)

(display "\n\nquasiquote:\n")
(display "ans: (list 3 4)   ") (write `(list ,(+ 1 2) 4)) (newline)
(display "ans: (a 3 4 5 6 b)   ")
(write `(a ,(+ 1 2) ,@(map abs '(4 -5 6)) b)) (newline)
(display "ans: ((foo 7) . cons)   ")
(write `((foo ,(- 10 3)) ,@(cdr '(c)) . ,(car '(cons)))) (newline)
(display "ans: #(10 5 2 4 3 8)   ")
(write `#(10 5 ,(sqrt 4) ,@(map sqrt '(16 9)) 8)) (newline)
(display "ans: (a `(b ,(+ 1 2) ,(foo 4 d) e) f)   ")
(write `(a `(b ,(+ 1 2) ,(foo ,(+ 1 3) d) e) f)) (newline)
(display "ans: (a `(b ,x ,'y d) e)   ")
(write (let ((name1 'x) (name2 'y)) `(a `(b ,,name1 ,',name2 d) e)))
(newline)
(display "ans: (list 3 4)   ")
(write (quasiquote (list (unquote (+ 1 2)) 4))) (newline)
(display "ans: `(list ,(+ 1 2) 4)   ")
(write '(quasiquote (list (unquote (+ 1 2)) 4))) (newline)

(display "\n\nTop level definitions:\n")
(display "ans: 6   ")
(define add3 (lambda (x) (+ x 3)))
(write (add3 3)) (newline)
(display "ans: 1   ")
(define first car)
(write (first '(1 2))) (newline)

(display "\n\nInternal definitions:\n")
(display "ans: 45   ")
(write
  (let ((x 5))
    (define foo (lambda (y) (bar x y)))
    (define bar (lambda (a b) (+ (* a b) a)))
    (foo (+ x 3))))
(newline)
(display "ans: 45   ")
(write
  (let ((x 5))
    (letrec ((foo (lambda (y) (bar x y)))
                (bar (lambda (a b) (+ (* a b) a))))
      (foo (+ x 3)))))
(newline)

(display "\n\nEquivalence predicates:\n")
(display "eqv?\n")
(display "ans: #t   ") (write (eqv? 'a 'a)) (newline)
(display "ans: #f   ") (write (eqv? 'a 'b)) (newline)
(display "ans: #t   ") (write (eqv? 2 2)) (newline)
(display "ans: #t   ") (write (eqv? '() '())) (newline)
(display "ans: #t   ") (write (eqv? 100000000 100000000)) (newline)
(display "ans: #f   ") (write (eqv? (cons 1 2) (cons 1 2))) (newline)
(display "ans: #f   ")
(write (eqv? (lambda () 1) (lambda () 2))) (newline)
(display "ans: #f   ") (write (eqv? #f 'nil)) (newline)
(display "ans: #t   ")
(write (let ((p (lambda (x) x))) (eqv? p p))) (newline)
(display "ans: unspecified   ")
(write (eqv? "" "")) (newline)
(display "ans: unspecified   ") (write (eqv? '#() '#())) (newline)
(display "ans: unspecified   ")
(write (eqv? (lambda (x) x) (lambda (x) x))) (newline)
(display "ans: unspecified   ")
(write (eqv? (lambda (x) x) (lambda (y) y))) (newline)
(display "ans: #t   ")
(define gen-counter
  (lambda ()
    (let ((n 0))
      (lambda () (set! n (+ n 1)) n))))
(write (let ((g (gen-counter))) (eqv? g g))) (newline)
(display "ans: #f   ")
(write (eqv? (gen-counter) (gen-counter))) (newline)
(display "ans: #t   ")
(define gen-loser
  (lambda ()
    (let ((n 0))
      (lambda () (set! n (+ n 1)) 27))))
(write (let ((g (gen-loser))) (eqv? g g))) (newline)
(display "ans: unspecified   ")
(write (eqv? (gen-loser) (gen-loser))) (newline)
(display "ans: unspecified   ")
(write (letrec ((f (lambda () (if (eqv? f g) 'both 'f)))
                      (g (lambda () (if (eqv? f g) 'both 'g))))
   (eqv? f g))) (newline)
(display "ans: #f   ")
(write (letrec ((f (lambda () (if (eqv? f g) 'f 'both)))
                      (g (lambda () (if (eqv? f g) 'g 'both))))
    (eqv? f g))) (newline)
(display "ans: unspecified   ")
(write (eqv? '(a) '(a))) (newline)
(display "ans: unspecified   ")
(write (eqv? "a" "a")) (newline)
(display "ans: unspecified   ")
(write (eqv? '(b) (cdr '(a b)))) (newline)
(display "ans: #t   ")
(write (let ((x '(a))) (eqv? x x))) (newline)

(display "eq?\n")
(display "ans: #t   ") (write (eq? 'a 'a)) (newline)
(display "ans: unspecified   ") (write (eq? '(a) '(a))) (newline)
(display "ans: #f   ") (write (eq? (list 'a) (list 'a))) (newline)
(display "ans: unspecified   ") (write (eq? "a" "a")) (newline)
(display "ans: unspecified   ") (write (eq? "" "")) (newline)
(display "ans: #t   ") (write (eq? '() '())) (newline)
(display "ans: unspecified   ") (write (eq? 2 2)) (newline)
(display "ans: unspecified   ") (write (eq? #\A #\A)) (newline)
(display "ans: #t   ") (write (eq? car car)) (newline)
(display "ans: unspecified ") (write (let ((n (+ 2 3))) (eq? n n))) (newline)
(display "ans: #t   ") (write (let ((x '(a))) (eq? x x))) (newline)
(display "ans: #t   ") (write (let ((x '#())) (eq? x x))) (newline)
(display "ans: #t   ") (write (let ((p (lambda (x) x))) (eq? p p))) (newline)

(display "equal?\n")
(display "ans: #t   ") (write (equal? 'a 'a)) (newline)
(display "ans: #t   ") (write (equal? '(a) '(a))) (newline)
(display "ans: #t   ") (write (equal? '(a (b) c) '(a (b) c))) (newline)
(display "ans: #t   ") (write (equal? "abc" "abc")) (newline)
(display "ans: #t   ") (write (equal? 2 2)) (newline)
(display "ans: #t   ") (write (equal? (make-vector 5 'a) (make-vector 5 'a)))
(newline)
(display "ans: unspecified   ")
(write (equal? (lambda (x) x) (lambda (y) y))) (newline)

(display "\n\nNumerical operations:\n")
(display "classification predicates\n")
(display "ans: #t   ") (write (complex? 3)) (newline)
(display "ans: #t   ") (write (real? 3)) (newline)
(display "ans: #t   ") (write (real? #e1e10)) (newline)
(display "ans: #t   ") (write (rational? 6/10)) (newline)
(display "ans: #t   ") (write (rational? 6/3)) (newline)
(display "ans: #t   ") (write (integer? 3.0)) (newline)
(display "ans: #t   ") (write (integer? 8/4)) (newline)

(display "max\n")
(display "ans: 4   ") (write (max 3 4)) (newline)
(display "ans: 4.0   ") (write (max 3.9 4)) (newline)

(display "basic arithmetic\n")
(display "ans: 7   ") (write (+ 3 4)) (newline)
(display "ans: 3   ") (write (+ 3)) (newline)
(display "ans: 0   ") (write (+)) (newline)
(display "ans: 4   ") (write (* 4)) (newline)
(display "ans: 1   ") (write (*)) (newline)
(display "ans: -1   ") (write (- 3 4)) (newline)
(display "ans: -6   ") (write (- 3 4 5)) (newline)
(display "ans: -3   ") (write (- 3)) (newline)
(display "ans: 3/20   ") (write (/ 3 4 5)) (newline)
(display "ans: 1/3   ") (write (/ 3)) (newline)

(display "integer division, remainder,modulo\n")
(display "ans: 1   ") (write (modulo 13 4)) (newline)
(display "ans: 1   ") (write (remainder 13 4)) (newline)
(display "ans: 3   ") (write (modulo -13 4)) (newline)
(display "ans: -1   ") (write (remainder -13 4)) (newline)
(display "ans: -3   ") (write (modulo 13 -4)) (newline)
(display "ans: 1   ") (write (remainder 13 -4)) (newline)
(display "ans: -1   ") (write (modulo -13 -4)) (newline)
(display "ans: -1   ") (write (remainder -13 -4)) (newline)
(display "ans: -1.0   ") (write (remainder -13 -4.0)) (newline)

(display "gcd, lcm\n")
(display "ans: 4   ") (write (gcd 32 -36)) (newline)
(display "ans: 0   ") (write (gcd)) (newline)
(display "ans: 288   ") (write (lcm 32 -36)) (newline)
(display "ans: 288.0   ") (write (lcm 32.0 -36)) (newline)
(display "ans: 1   ") (write (lcm)) (newline)

(display "numerator, denominator\n")
(display "ans: 3   ") (write (numerator (/ 6 4))) (newline)
(display "ans: 2   ") (write (denominator (/ 6 4))) (newline)
(display "ans: 2.0   ")
(write (denominator (exact->inexact (/ 6 4)))) (newline)

(display "floor, ceiling, truncate, round\n")
(display "ans: -5.0   ") (write (floor -4.3)) (newline)
(display "ans: -4.0   ") (write (ceiling -4.3)) (newline)
(display "ans: -4.0   ") (write (truncate -4.3)) (newline)
(display "ans: -4.0   ") (write (round -4.3)) (newline)
(display "ans: 3.0   ") (write (floor 3.5)) (newline)
(display "ans: 4.0   ") (write (ceiling 3.5)) (newline)
(display "ans: 3.0   ") (write (truncate 3.5)) (newline)
(display "ans: 4.0 (inexact)   ") (write (round 3.5)) (newline)
(display "ans: 4 (exact)   ") (write (round 7/2)) (newline)
(display "ans: 7   ") (write (round 7)) (newline)

(display "\n\nrationalize:\n")
(display "ans: 1/3 (exact)   ")
(write (rationalize (inexact->exact .3) 1/10)) (newline)
(display "ans: #i1/3 (inexact)   ")
(write (rationalize .3 1/10)) (newline)

(display "\n\nstring->number\n")
(display "ans: 100   ") (write (string->number "100")) (newline)
(display "ans: 256   ") (write (string->number "100" 16)) (newline)
(display "ans: 100.0   ") (write (string->number "1e2")) (newline)

(display "\n\nBoolean operations:\n")
(display "ans: #t   ") (write #t) (newline)
(display "ans: #f   ") (write #f) (newline)
(display "ans: #f   ") (write '#f) (newline)
(display "ans: #f   ") (write (not #t)) (newline)
(display "ans: #f   ") (write (not 3)) (newline)
(display "ans: #f   ") (write (not (list 3))) (newline)
(display "ans: #t   ") (write (not #f)) (newline)
(display "ans: #f   ") (write (not '())) (newline)
(display "ans: #f   ") (write (not (list))) (newline)
(display "ans: #f   ") (write (not 'nil)) (newline)
(display "ans: #t   ") (write (boolean? #f)) (newline)
(display "ans: #f   ") (write (boolean? 0)) (newline)
(display "ans: #f   ") (write (boolean? '())) (newline)

(display "\n\nList operations:\n")
(display "define/set:\n")
(display "ans: (a b c)   ")
(define x (list 'a 'b 'c))
(define y x)
(write y) (newline)
(display "ans: #t   ") (write (list? y)) (newline)
(display "ans: unspecified   ") (write (set-cdr! x 4)) (newline)
(display "ans: (a . 4)   ") (write x) (newline)
(display "ans: #t   ") (write (eqv? x y)) (newline)
(display "ans: (a . 4)   ") (write y) (newline)
(display "ans: #f   ") (write (list? y)) (newline)
;(display "ans: unspecified   ") (write (set-cdr! x x)) (newline)
;(display "ans: #f   ") (write (list? x)) (newline)

(display "predicates:\n")
(display "ans: #t   ") (write (pair? '(a . b))) (newline)
(display "ans: #t   ") (write (pair? '(a b c))) (newline)
(display "ans: #f   ") (write (pair? '())) (newline)
(display "ans: #f   ") (write (pair? '#(a b))) (newline)

(display "cons, car, cdr\n")
(display "ans: (a)   ") (write (cons 'a '())) (newline)
(display "ans: ((a) b c d)   ") (write (cons '(a) '(b c d))) (newline)
(display "ans: (\"a\" b c)   ") (write (cons "a" '(b c))) (newline)
(display "ans: (a . 3)   ") (write (cons 'a 3)) (newline)
(display "ans: ((a b) . c)   ") (write (cons '(a b) 'c)) (newline)
(display "ans: a   ") (write (car '(a b c))) (newline)
(display "ans: (a)   ") (write (car '((a) b c))) (newline)
(display "ans: 1   ") (write (car '(1 . 2))) (newline)
(display "ans: error   ") (write (car '())) (newline)
(display "ans: (b c d)   ") (write (cdr '((a) b c d))) (newline)
(display "ans: 2   ") (write (cdr '(1 . 2))) (newline)
(display "ans: error   ") (write (cdr '())) (newline)

(display "set-car!\n")
(display "ans: unspecified   ")
(define (f) (list 'not-a-constant-list))
(define (g) '(constant-list))
(write (set-car! (f) 3)) (newline)
(display "ans: error   ")
(write (set-car! (g) 3)) (newline)

(display "list?\n")
(display "ans: #t   ") (write (list? '(a b c))) (newline)
(display "ans: #t   ") (write (list? '())) (newline)
(display "ans: #f   ") (write (list? '(a . b))) (newline)
(display "ans: #f   ")
(write (let ((x (list 'a))) (set-cdr! x x) (list? x))) (newline)

(display "list\n")
(display "ans: (a 7 c)   ") (write (list 'a (+ 3 4) 'c)) (newline)
(display "ans: ()   ") (write (list)) (newline)

(display "length\n")
(display "ans: 3   ") (write (length '(a b c))) (newline)
(display "ans: 3   ") (write (length '(a (b) (c d e)))) (newline)
(display "ans: 0   ") (write (length '())) (newline)

(display "append\n")
(display "ans: (x y)   ") (write (append '(x) '(y))) (newline)
(display "ans: (a b c d)   ") (write (append '(a) '(b c d))) (newline)
(display "ans: (a (b) (c))   ") (write (append '(a (b)) '((c)))) (newline)
(display "ans: (a b c . d)   ") (write (append '(a b) '(c . d))) (newline)
(display "ans: a   ") (write (append '() 'a)) (newline)

(display "reverse\n")
(display "ans: (c b a)   ") (write (reverse '(a b c))) (newline)
(display "ans: ((e (f)) d (b c) a)   ") (write (reverse '(a (b c) d (e (f))))) (newline)

(display "list-ref\n")
(display "ans: c   ") (write (list-ref '(a b c d) 2)) (newline)
(display "ans: c   ")
(write (list-ref '(a b c d) (inexact->exact (round 1.8)))) (newline)

(display "memq, memv, member\n")
(display "ans: (a b c)   ") (write (memq 'a '(a b c))) (newline)
(display "ans: (b c)   ") (write (memq 'b '(a b c))) (newline)
(display "ans: #f   ") (write (memq 'a '(b c d))) (newline)
(display "ans: #f   ") (write (memq (list 'a) '(b (a) c))) (newline)
(display "ans: ((a) c)   ") (write (member (list 'a) '(b (a) c))) (newline)
(display "ans: unspecified   ") (write (memq 101 '(100 101 102))) (newline)
(display "ans; (101 102)   ") (write (memv 101 '(100 101 102))) (newline)

(display "assq, assv, assoc\n")
(display "ans: (a 1)   ")
(define e '((a 1) (b 2) (c 3)))
(write (assq 'a e)) (newline)
(display "ans: (b 2)   ") (write (assq 'b e)) (newline)
(display "ans: #f   ") (write (assq 'd e))  (newline)
(display "ans: #f   ")
(write (assq (list 'a) '(((a)) ((b)) ((c))))) (newline)
(display "ans: ((a))   ")
(write (assoc (list 'a) '(((a)) ((b)) ((c))))) (newline)
(display "ans: unspecified   ")
(write (assq 5 '((2 3) (5 7) (11 13)))) (newline)
(display "ans: (5 7)   ")
(write (assv 5 '((2 3) (5 7) (11 13)))) (newline)

(display "\n\nSymbols:\n")
(display "symbol?\n")
(display "ans: #t   ") (write (symbol? 'foo)) (newline)
(display "ans: #t   ") (write (symbol? (car '(a b)))) (newline)
(display "ans: #f   ") (write (symbol? "bar")) (newline)
(display "ans: #t   ") (write (symbol? 'nil)) (newline)
(display "ans: #f   ") (write (symbol? '())) (newline)
(display "ans: #f   ") (write (symbol? #f)) (newline)

(display "symbol->string\n")
(display "ans: \"flying-fish\"   ")
(write (symbol->string 'flying-fish)) (newline)
(display "ans: \"martin\"   ")
(write (symbol->string 'Martin)) (newline)
(display "ans: \"Malvina\"   ")
(write (symbol->string (string->symbol "Malvina"))) (newline)

(display "string->symbol\n")
(display "ans: mISSISSIppi   ")
(write (string->symbol "mISSISSIppi")) (newline)
(display "ans: #f   ")
(write (eq? 'bitBlt (string->symbol "bitBlt"))) (newline)
(display "ans: #t   ")
(write (eq? 'JollyWog (string->symbol (symbol->string 'JollyWog))))
(newline)
(display "ans: #t   ")
(write (string=? "K. Harper, M.D."
                        (symbol->string (string->symbol "K. Harper, M.D."))))
(newline)

(display "\n\nCharacters:\n")
(display "ans: #t   ") (write (char-ci=? #\A #\a)) (newline)

(display "\n\nStrings:\n")
(display "ans: unspecified   ")
(define (f) (make-string 3 #\*))
(define (g) "***")
(write (string-set! (f) 0 #\?)) (newline)
(display "ans: error   ")
(write (string-set! (g) 0 #\?)) (newline)
(display "ans: error   ")
(write (string-set! (symbol->string 'immutable) 0 #\?)) (newline)

(display "\n\nVectors:\n")
(display "ans: #(a b c)   ") (write (vector 'a 'b 'c)) (newline)
(display "ans: 8   ") (write (vector-ref '#(1 1 2 3 5 8 13 21) 5)) (newline)
(display "ans: 13   ")
(write (vector-ref '#(1 1 2 3 5 8 13 21)
                           (let ((i (round (* 2 (acos -1)))))
                             (if (inexact? i)
                                 (inexact->exact i) i)))) (newline)
(display "ans: #(0 (\"Sue\" \"Sue\") \"Anna\")   ")
(write (let ((vec (vector 0 '(2 2 2 2) "Anna")))
                (vector-set! vec 1 '("Sue" "Sue")) vec)) (newline)
(display "ans: error   ") (write (vector-set! '#(0 1 2) 1 "doe")) (newline)
(display "ans: (dah dah didah)   ")
(write (vector->list '#(dah dah didah))) (newline)
(display "ans: #(dididit dah)   ")
(write (list->vector '(dididit dah))) (newline)

(display "\n\nControl features:\n")
(display "procedure?\n")
(display "ans: #t   ") (write (procedure? car)) (newline)
(display "ans: #f   ") (write (procedure? 'car)) (newline)
(display "ans: #t   ") (write (procedure? (lambda (x) (* x x)))) (newline)
(display "ans: #f   ") (write (procedure? '(lambda (x) (* x x)))) (newline)

(display "apply\n")
(display "ans: 7   ") (write (apply + (list 3 4))) (newline)
(display "ans: 30   ")
(define compose (lambda (f g) (lambda args (f (apply g args)))))
(write ((compose sqrt *) 12 75)) (newline)

(display "map\n")
(display "ans: (b e h)   ")
(write (map cadr '((a b) (d e) (g h)))) (newline)
(display "ans: (1 4 27 256 3125)   ")
(write (map (lambda (n) (expt n n)) '(1 2 3 4 5))) (newline)
(display "ans: (5 7 9)   ") (write (map + '(1 2 3) '(4 5 6))) (newline)
(display "ans: (1 2) or (2 1)   ")
(write (let ((count 0))
                (map (lambda (ignored) (set! count (+ count 1)) count)
                        '(a b)))) (newline)

(display "for-each\n")
(display "ans: #(0 1 4 9 16)   ")
(write (let ((v (make-vector 5)))
                (for-each (lambda (i) (vector-set! v i (* i i))) '(0 1 2 3 4)) v))
(newline)

(display "delay/force\n")
(display "ans: 3   ")
(write (force (delay (+ 1 2)))) (newline)
(display "ans: (3 3)   ")
(write
  (let ((p (delay (+ 1 2))))
    (list (force p) (force p)))
) (newline)
(display "ans: 2   ")
  (define a-stream
    (letrec ((next
            (lambda (n)
              (cons n (delay (next (+ n 1)))))))
    (next 0)))
  (define head car)
  (define tail
    (lambda (stream) (force (cdr stream))))
(write
      (head (tail (tail a-stream)))
) (newline)

(define count 0)
(define p
  (delay (begin (set! count (+ count 1))
                (if (> count x)
                    count
                    (force p)))))
(define x 5)

(display "ans: [promise]   ")
(write p) (newline)
(display "ans: 6   ")
(write (force p)) (newline)
(display "ans: [promise]   ")
(write p) (newline)
(display "ans: 6   ")
(write (begin (set! x 100) (force p))) (newline)

